package com.ziytek.web.citizen.service;


import com.google.gson.Gson;
import com.ziytek.web.citizen.constant.NumConstant;
import com.ziytek.web.citizen.constant.ServerConstant;
import com.ziytek.web.citizen.enums.ResponseEnum;
import com.ziytek.web.citizen.mapper.BatchNoMapper;
import com.ziytek.web.citizen.model.bean.BatchNoDetail;
import com.ziytek.web.citizen.model.req.BatchNoQueryReq;
import com.ziytek.web.citizen.model.rsp.BatchNoQueryRsp;
import com.ziytek.web.citizen.model.vo.BatchNoVo;
import com.ziytek.web.citizen.model.vo.DayBatchNoVo;
import com.ziytek.web.citizen.pojo.basic.BatchNo;
import com.ziytek.web.citizen.util.DateTimeUtils;
import com.ziytek.web.citizen.util.HexUtil;
import com.ziytek.web.citizen.util.StringUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * 批次服务类
 *
 * @author fenghx
 */
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class BatchNoService {

    private final Gson gson;
    private final BatchNoMapper batchNoMapper;

    public void insertBatchNo(Integer cabinetNo) {
        if (null == cabinetNo) {
            return;
        }

        var nowTime = System.currentTimeMillis();
        var batchNo = new BatchNo();
        batchNo.setCabinetNo(cabinetNo);
        batchNo.setCreateTime(nowTime);
        batchNo.setUpdateTime(nowTime);
        var day = DateTimeUtils.toDateInt(nowTime, "yyyyMMdd");
        var batchNum = DateTimeUtils.toDateInt(nowTime, "HHmmss");
        batchNo.setDay(day);
        var batchNoStr = HexUtil.fillZero(String.valueOf(batchNum), NumConstant.INT_SIX);
        batchNo.setBatchNo(day + batchNoStr);
        insertBatchNo(batchNo);
        log.info("新增批次号:[{}]-{}", cabinetNo, gson.toJson(batchNo));
    }

    public void insertBatchNo(BatchNo batchNo) {
        if (null == batchNo) {
            return;
        }
        batchNoMapper.insertData(batchNo);
    }

    public void updateBatchNo(BatchNo batchNo) {
        if (null == batchNo) {
            return;
        }
        batchNoMapper.updateData(batchNo);
    }

    public BatchNo queryOne(Integer cabinetNo) {
        return null == cabinetNo ? null : batchNoMapper.queryLastBatchNo(cabinetNo);
    }

    public List<BatchNo> queryList(Integer cabinetNo, Integer day) {
        if (null == cabinetNo || null == day) {
            return Collections.emptyList();
        }
        return batchNoMapper.queryBatchNoList(cabinetNo, day);
    }

    public BatchNoQueryRsp batchNoQuery(BatchNoQueryReq req) {
        var rsp = new BatchNoQueryRsp();
        rsp.setRetErrorData("查询无数据");

        var day = req.getDay();
        var cabinetNo = req.getCabinetNo();
        int dayInt = DateTimeUtils.toDateInt(day);
        int cabinetNoInt = StringUtil.isEmpty(cabinetNo) ? -1 : Integer.parseInt(cabinetNo);
        List<BatchNo> batchNoList = null;
        if (cabinetNoInt < NumConstant.INT_ZERO) {
            batchNoList = batchNoMapper.queryBatchNoListNot();
        }
        if (cabinetNoInt >= NumConstant.INT_ZERO && dayInt < NumConstant.INT_ZERO) {
            batchNoList = batchNoMapper.queryBatchNoListByCabinetNo(cabinetNoInt);
        }

        if (cabinetNoInt >= NumConstant.INT_ZERO && dayInt >= NumConstant.INT_ZERO) {
            batchNoList = queryList(cabinetNoInt, dayInt);
        }

        if (CollectionUtils.isEmpty(batchNoList)) {
            return rsp;
        }

        List<BatchNoVo> voList = new ArrayList<>();
        Map<String, List<DayBatchNoVo>> map = new HashMap<>();
        for (var bn : batchNoList) {
            var dayNum = bn.getDay();
            var batchNo = bn.getBatchNo();
            var key = String.valueOf(bn.getCabinetNo());
            List<DayBatchNoVo> dayBatchNoVos = map.get(key);
            if (CollectionUtils.isEmpty(dayBatchNoVos)) {
                dayBatchNoVos = new ArrayList<>();
            }

            var dayStr = DateTimeUtils.getTimeString(String.valueOf(dayNum), ServerConstant.DATE_FORMAT_DAY_TWO, ServerConstant.DATE_FORMAT_DAY_THREE);
            var dayVos = dayBatchNoVos.stream().filter(d -> d != null && d.getDay().equals(dayStr)).toList();
            var dayVo = dayVos.isEmpty() ? null : dayVos.getFirst();
            if (null == dayVo) {
                dayVo = new DayBatchNoVo();
            }

            dayVo.setDay(dayStr);

            var dateString = DateTimeUtils.getTimeString(batchNo, ServerConstant.DATE_FORMAT_TWO, ServerConstant.DATE_FORMAT);
            dayVo.setList(dateString);
            var detail = new BatchNoDetail();
            detail.setBatchNo(dateString);
            detail.setHasCapacity(null != bn.getHasCapacity() && NumConstant.INT_ONE == bn.getHasCapacity());
            dayVo.setDetailList(detail);

            // 删除数据
            dayBatchNoVos.removeIf(d -> d != null && d.getDay().equals(dayStr));
            dayBatchNoVos.add(dayVo);

            map.put(key, dayBatchNoVos);
        }

        for (var key : map.keySet()) {
            var vo = new BatchNoVo();
            vo.setCabinetNo(key);
            vo.setList(map.get(key));
            voList.add(vo);
        }

        rsp.setRetSuccessData(voList);
        rsp.setRetCode(ServerConstant.SUCCESS);
        rsp.setRetMsg(ResponseEnum.SUCCESS.getDesc());
        return rsp;
    }
}
